﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using FIFP.Common;
using System.Collections.ObjectModel;
using FIFP.DashBoard.Model;
using Telerik.Windows.Controls;
using System.Collections.Generic;
using System.Linq;
using FIFP.DashBoard.Helper;
using System.ComponentModel;
using FIFP.DashBoard.Converters;
using FIFP.DashBoard.Views;
using System.ComponentModel.DataAnnotations;
using System.Collections;
using System.Linq.Expressions;

namespace FIFP.DashBoard.ViewModel
{
    public class ShutdownMngVM : ViewModelCore, INotifyPropertyChanged, INotifyDataErrorInfo
    {
        #region Variables
        private List<FIFPAppointment> lsdActivities;
        private List<string> closedStringList = new List<string>();
        private List<FIFPAppointment> activityList;
        private ObservableCollection<FIFPAppointment> linkedShutdownList;
        private ObservableCollection<FIFPAppointment> filteredLinkedShutdownList;
        private string selectedClosedString;
        public event EventHandler<CustomEventArgs<AppointmentGroup>> OnAppointmentDataCompleted;

        private List<FIFPAppointment> activityListWithSelectedUnit;
        private ObservableCollection<FIFPAppointment> filteredActivityListWithSelectedUnit;
        PercentagePopup popup;
        private readonly ICollection<ValidationResult> _validationResults;
        private bool IsSIMOPS;
        #endregion

        #region Properties

        private ObservableCollection<Unit> filteredLSDLocations;
        public ObservableCollection<Unit> FilteredLSDLocations
        {
            get { return filteredLSDLocations; }
            set { SetPropertyValue(() => FilteredLSDLocations, value, val => filteredLSDLocations = val); }
        }

        private List<Unit> linkedShutdownLocations;
        public List<Unit> LinkedShutdownLocations
        {
            get { return linkedShutdownLocations; }
            set { SetPropertyValue(() => LinkedShutdownLocations, value, val => linkedShutdownLocations = val); }
        }

        private Unit selectedLSDLocation;
        public Unit SelectedLSDLocation
        {
            get { return selectedLSDLocation; }
            set { SetPropertyValue(() => SelectedLSDLocation, value, val => selectedLSDLocation = val); }
        }

        public List<FIFPAppointment> LsdActivities
        {
            get { return lsdActivities; }
            set { SetPropertyValue(() => LsdActivities, value, val => lsdActivities = val); }
        }

        public string SelectedClosedString
        {
            get { return selectedClosedString; }
            set { SetPropertyValue(() => SelectedClosedString, value, val => selectedClosedString = val); }
        }

        public List<string> ClosedStringList
        {
            get { return closedStringList; }
            set { SetPropertyValue(() => ClosedStringList, value, val => closedStringList = val); }
        }


        public ObservableCollection<FIFPAppointment> LinkedShutdownList
        {
            get { return linkedShutdownList; }
            set { SetPropertyValue(() => LinkedShutdownList, value, val => linkedShutdownList = val); }
        }

        public ObservableCollection<FIFPAppointment> FilteredLinkedShutdownList
        {
            get { return filteredLinkedShutdownList; }
            set { SetPropertyValue(() => FilteredLinkedShutdownList, value, val => filteredLinkedShutdownList = val); }
        }

        public List<FIFPAppointment> ActivityList
        {
            get { return activityList; }
            set { SetPropertyValue(() => ActivityList, value, val => activityList = val); }
        }

        private bool isCombinedTowerEnabled = false;
        public bool IsCombinedTowerEnabled
        {
            get { return isCombinedTowerEnabled; }
            set { SetPropertyValue(() => IsCombinedTowerEnabled, value, val => isCombinedTowerEnabled = val); }
        }

        private bool isApplySIMOPSEnabled = false;
        public bool IsApplySIMOPSEnabled
        {
            get { return isApplySIMOPSEnabled; }
            set { SetPropertyValue(() => IsApplySIMOPSEnabled, value, val => isApplySIMOPSEnabled = val); }
        }

        private bool isCancelSIMOPSEnabled = false;
        public bool IsCancelSIMOPSEnabled
        {
            get { return isCancelSIMOPSEnabled; }
            set { SetPropertyValue(() => IsCancelSIMOPSEnabled, value, val => isCancelSIMOPSEnabled = val); }
        }

        private bool isApplyCrossLineEnabled = false;
        public bool IsApplyCrossLineEnabled
        {
            get { return isApplyCrossLineEnabled; }
            set { SetPropertyValue(() => IsApplyCrossLineEnabled, value, val => isApplyCrossLineEnabled = val); }
        }

        private bool isCancelCrossLineEnabled = false;
        public bool IsCancelCrossLineEnabled
        {
            get { return isCancelCrossLineEnabled; }
            set { SetPropertyValue(() => IsCancelCrossLineEnabled, value, val => isCancelCrossLineEnabled = val); }
        }
        private FIFPAppointment selectedActivity;
        public FIFPAppointment SelectedActivity
        {
            get { return selectedActivity; }
            set { SetPropertyValue(() => SelectedActivity, value, val => selectedActivity = val); }
        }

        private FIFPAppointment modifiedSelectedActivity;
        public FIFPAppointment ModifiedSelectedActivity
        {
            get { return modifiedSelectedActivity; }
            set { SetPropertyValue(() => ModifiedSelectedActivity, value, val => modifiedSelectedActivity = val); }
        }

        public List<FIFPAppointment> ActivityListWithSelectedUnit
        {
            get { return activityListWithSelectedUnit; }
            set { SetPropertyValue(() => ActivityListWithSelectedUnit, value, val => activityListWithSelectedUnit = val); }
        }

        public ObservableCollection<FIFPAppointment> FilteredActivityListWithSelectedUnit
        {
            get { return filteredActivityListWithSelectedUnit; }
            set { SetPropertyValue(() => FilteredActivityListWithSelectedUnit, value, val => filteredActivityListWithSelectedUnit = val); }
        }
        private ObservableCollection<FIFPAppointment> modifiedLinkedShutdownList = new ObservableCollection<FIFPAppointment>();
        public ObservableCollection<FIFPAppointment> ModifiedLinkedShutdownList
        {
            get { return modifiedLinkedShutdownList; }
            set { SetPropertyValue(() => ModifiedLinkedShutdownList, value, val => modifiedLinkedShutdownList = val); }
        }


        private List<Unit> treeViewUnitList = new List<Unit>();
        public List<Unit> TreeViewUnitList
        {
            get { return treeViewUnitList; }
            set { SetPropertyValue(() => TreeViewUnitList, value, val => treeViewUnitList = val); }
        }

        private List<Unit> unitList = new List<Unit>();
        public List<Unit> UnitList
        {
            get { return unitList; }
            set { SetPropertyValue(() => UnitList, value, val => unitList = val); }
        }



        private int capacityPercentage = 100;
        [Display(Name = FIFPConstants.DISPLAY_PERCENTAGE)]
        [CustomValidation(typeof(ErrorValidation), FIFPConstants.VALIDATE_PERCENTAGE)]
        public int CapacityPercentage
        {
            get { return capacityPercentage; }
            set
            {
                if (CapacityPercentage != value)
                {
                    capacityPercentage = value;
                    OnPropertyChanged(() => this.capacityPercentage);
                }
            }
        }

        private int reducedCapacity = 0;
        public int ReducedCapacity
        {
            get { return reducedCapacity; }
            set { SetPropertyValue(() => ReducedCapacity, value, val => reducedCapacity = val); }
        }

        private string _UnitName = string.Empty;
        [Display(Name = FIFPConstants.DISPLAY_UNITNAME)]
        [CustomValidation(typeof(ErrorValidation), FIFPConstants.VALIDATE_UNITNAME)]
        public string UnitName
        {
            get { return _UnitName; }
            set
            {
                if (_UnitName != value)
                {
                    _UnitName = value;
                    OnPropertyChanged(() => this._UnitName);
                }
            }
        }

        private bool isUnitNameExist = false;
        public bool IsUnitNameExist
        {
            get { return isUnitNameExist; }
            set { SetPropertyValue(() => IsUnitNameExist, value, val => isUnitNameExist = val); }
        }

        private Grid treeViewGrid;
        public Grid TreeViewGrid
        {
            get { return treeViewGrid; }
            set { SetPropertyValue(() => TreeViewGrid, value, val => treeViewGrid = val); }
        }
        private bool isEnabledRaducedCapacity = false;
        public bool IsEnabledRaducedCapacity
        {
            get { return isEnabledRaducedCapacity; }
            set { SetPropertyValue(() => IsEnabledRaducedCapacity, value, val => isEnabledRaducedCapacity = val); }
        }

        private Unit selectedTreeViewUnit;
        public Unit SelectedTreeViewUnit
        {
            get { return selectedTreeViewUnit; }
            set { SetPropertyValue(() => SelectedTreeViewUnit, value, val => selectedTreeViewUnit = val); }
        }

        #endregion

        #region Commands
        private ICommand _ClosedStringSelectionCommand;
        public ICommand ClosedStringSelectionCommand
        {
            get
            {
                return _ClosedStringSelectionCommand ??
                        (_ClosedStringSelectionCommand = new RelayCommand<ComboBox>(ClosedStringFilter));
            }
        }

        private ICommand _TreeviewSelectionChanged;
        public ICommand TreeviewSelectionChanged
        {
            get
            {
                return _TreeviewSelectionChanged ??
                        (_TreeviewSelectionChanged = new RelayCommand<TreeView>(UnitTreeviewSelectionChanged));
            }
        }

        private ICommand _ActivitySelectChanged;
        public ICommand ActivitySelectChanged
        {
            get
            {
                return _ActivitySelectChanged ??
                        (_ActivitySelectChanged = new RelayCommand<DataGrid>(ActivityDatagridSelectionChange));
            }
        }

        private ICommand _ModifiedActivitySelectChanged;
        public ICommand ModifiedActivitySelectChanged
        {
            get
            {
                return _ModifiedActivitySelectChanged ??
                        (_ModifiedActivitySelectChanged = new RelayCommand<DataGrid>(ModifiedActivityDatagridSelectionChange));
            }
        }


        private ICommand _SIMOPSClickCommand;
        public ICommand SIMOPSClickCommand
        {
            get
            {
                return _SIMOPSClickCommand ??
                        (_SIMOPSClickCommand = new RelayCommand<Button>(ReloadTimelineViewBySIMOPS));
            }
        }

        private ICommand _CrossingLineClickCommand;
        public ICommand CrossingLineClickCommand
        {
            get
            {
                return _CrossingLineClickCommand ??
                        (_CrossingLineClickCommand = new RelayCommand<Button>(ReloadTimelineViewByCrossingLine));
            }
        }

        private ICommand _LSDLocationSelectionChanged;
        public ICommand LSDLocationSelectionChanged
        {
            get
            {
                return _LSDLocationSelectionChanged ??
                        (_LSDLocationSelectionChanged = new RelayCommand<DataGrid>(LSDLocationGridSelectionChange));
            }
        }
        private ICommand _CancelCommand;
        public ICommand CancelCommand
        {
            get { return _CancelCommand ?? (_CancelCommand = new RelayCommand<Button>(HidePopup)); }
        }
        private ICommand _WarningCommand;
        public ICommand WarningCommand
        {
            get
            {
                return _WarningCommand ??
                        (_WarningCommand = new RelayCommand<Button>(ShowPopup));
            }
        }

        private ICommand _UnitNameSearchCommand;
        public ICommand UnitNameSearchCommand
        {
            get
            {
                return _UnitNameSearchCommand ??
                        (_UnitNameSearchCommand = new RelayCommand<object>(SearchByUnitName));
            }
        }

        private ICommand _TextBoxLoadCommand;
        public ICommand TextBoxLoadCommand
        {
            get
            {
                return _TextBoxLoadCommand ??
                        (_TextBoxLoadCommand = new RelayCommand<TextBox>(LoadTextBox));
            }
        }
        private ICommand _RCTextBoxLoadCommand;
        public ICommand RCTextBoxLoadCommand
        {
            get
            {
                return _RCTextBoxLoadCommand ??
                        (_RCTextBoxLoadCommand = new RelayCommand<TextBox>(LoadRCTextBox));
            }
        }
        private ICommand _ReducedCapacityCommand;
        public ICommand ReducedCapacityCommand
        {
            get
            {
                return _ReducedCapacityCommand ??
                        (_ReducedCapacityCommand = new RelayCommand<object>(CalculateReducedCapacity));
            }
        }

        private ICommand _CencelSIMOPSEvent;
        public ICommand CencelSIMOPSEvent
        {
            get
            {
                return _CencelSIMOPSEvent ??
                        (_CencelSIMOPSEvent = new RelayCommand<Button>(CancelSIMOPS));
            }
        }

        private ICommand _CencelCrossingEvent;
        public ICommand CencelCrossingEvent
        {
            get
            {
                return _CencelCrossingEvent ??
                        (_CencelCrossingEvent = new RelayCommand<Button>(CancelCrossingLine));
            }
        }
        private ICommand _TreeviewGridLoaded;
        public ICommand TreeviewGridLoaded
        {
            get
            {
                return _TreeviewGridLoaded ??
                        (_TreeviewGridLoaded = new RelayCommand<Grid>(LoadTreeviewGrid));
            }
        }
        #endregion

        #region Constructor
        public ShutdownMngVM()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                _validationResults = new List<ValidationResult>();
                filteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>();
                ServiceLocator.Get<MainPageVM>().OnLinkedShutdownClick += new EventHandler(ShutdownMngVM_OnLinkedShutdownClick);
                ServiceLocator.Get<FilterVM>().OnCombinedTowerClick += new EventHandler(ShutdownMngVM_OnCombinedTowerClick);
                LoadCombo();
            }
        }

        void ShutdownMngVM_OnCombinedTowerClick(object sender, EventArgs e)
        {
            if (ServiceLocator.Get<FilterVM>().IsCombinedTowerChecked)
            {
                FilteredLSDLocations = new ObservableCollection<Unit>(from item in LinkedShutdownLocations
                                                                      where item.FluidType == FIFPConstants.FLUIDTYPE_COMBINED
                                                                      select item);
            }
            else
            {
                FilteredLSDLocations = new ObservableCollection<Unit>(LinkedShutdownLocations);
            }
            FilteredActivityListWithSelectedUnit = new ObservableCollection<FIFPAppointment>();
        }
        #endregion

        #region Get the original plans from Import UI while we click linked shutdown button from MainPage
        void ShutdownMngVM_OnLinkedShutdownClick(object sender, EventArgs e)
        {
            ServiceLocator.Get<FilterVM>().IsDivisionEnabled = false;
            LinkedShutdownLocations = new List<Unit>();
            ServiceLocator.Get<AppointmentVM>().RadScheduleViewDragDropBehavior = new ScheduleDragDropBehavior();
            ActivityList = ServiceLocator.Get<ImportVM>().ImportPlans;
            UnitList = ServiceLocator.Get<ImportVM>().UnitList;
            foreach (Unit unit in UnitList)
            {
                unit.UnitNameTextColor = (unit.FluidType == FIFPConstants.FLUIDTYPE_OIL) ? new SolidColorBrush(new Color() { R = 0xFF, G = 0x59, B = 0x59, A = 0xFF }) : (unit.FluidType == FIFPConstants.FLUIDTYPE_WATER) ? new SolidColorBrush(new Color() { R = 0x4B, G = 0xAC, B = 0xC6, A = 0xFF }) : (unit.FluidType == FIFPConstants.FLUIDTYPE_GAS) ? new SolidColorBrush(new Color() { R = 0x93, G = 0xA8, B = 0x2A, A = 0xFF }) : new SolidColorBrush(new Color() { R = 0x17, G = 0x36, B = 0x5D, A = 0xFF });
                /*if (unit.UnitType != FIFPConstants.UNITTYPE_STRING && unit.UnitType != FIFPConstants.UNITTYPE_WELL && !LinkedShutdownLocations.Contains(unit))
                    LinkedShutdownLocations.Add(unit);*/
            }

            if (ActivityList != null && ActivityList.Count > 0)
            {
                foreach (FIFPAppointment activity in ActivityList)
                {
                    activity.LsdPlans.ForEach(s => { s.IsAppointmentDelete = true; });//We set to true that delete linked shutdown activity in LSD page
                    if (activity.UnitType == FIFPConstants.UNITTYPE_RADIAL || activity.UnitType == FIFPConstants.UNITTYPE_TOWER || activity.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
                    {
                        foreach (FIFPAppointment appointment in activity.LsdPlans)
                        {
                            appointment.Start = activity.Start; appointment.End = activity.End;
                        }
                        activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => l.UnitType == FIFPConstants.UNITTYPE_TOWER && l.IsLinkedShutdownPlan == true));
                    }
                    else if (activity.UnitType == FIFPConstants.UNITTYPE_WELL && activity.ActivityCode == FIFPConstants.ACTIVITY_TYPE_RIG)
                    {
                        // No need to Well activities in LSD Location list. even no need to add RIG activity bcoz it's already captured in Tower activity.
                        //Unit unit = UnitList.Where(u => u.UnitName == activity.UnitName && u.UnitType == activity.UnitType).FirstOrDefault();
                        //if (!LinkedShutdownLocations.Contains(unit))
                        //{
                        //    LinkedShutdownLocations.Add(unit);
                        //}
                        //foreach (FIFPAppointment appointment in activity.LsdPlans) //Temporary comment
                        //{
                        //    appointment.Start = activity.Start; appointment.End = activity.End;
                        //}
                        //activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(l => l.UnitType == FIFPConstants.UNITTYPE_TOWER && l.IsLinkedShutdownPlan == true));
                    }
                    else if (activity.UnitType == FIFPConstants.UNITTYPE_COMBINED_TOWER)
                    {
                        foreach (FIFPAppointment appointment in activity.LsdPlans)
                        {
                            appointment.Start = activity.Start; appointment.End = activity.End;
                        }
                        activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>(activity.LsdPlans.Where(s => s.FluidType == s.CombinedTowerLSDType && s.IsLinkedShutdownPlan == true));
                    }

                    else if (activity.UnitType != FIFPConstants.UNITTYPE_WELL || activity.UnitType != FIFPConstants.UNITTYPE_STRING)
                    {
                        activity.FilteredLsdPlans = new ObservableCollection<FIFPAppointment>();
                    }
                    Unit unit = UnitList.Where(u => u.UnitName == activity.UnitName && u.UnitType == activity.UnitType).FirstOrDefault();
                    if (unit != null && unit.UnitType != FIFPConstants.UNITTYPE_STRING && unit.UnitType != FIFPConstants.UNITTYPE_WELL && !LinkedShutdownLocations.Contains(unit) && activity.FilteredLsdPlans.Count > 0)
                    {
                        LinkedShutdownLocations.Add(unit);
                    }
                }

                List<FIFPAppointment> listForScheduleView = new List<FIFPAppointment>();
                if (FilteredLinkedShutdownList != null && FilteredLinkedShutdownList.Count > 0 && SelectedActivity != null)
                    listForScheduleView.Add(SelectedActivity);
                listForScheduleView.AddRange(FilteredLinkedShutdownList);
                LoadTimelineView(listForScheduleView);
            }
            FilteredLSDLocations = new ObservableCollection<Unit>(LinkedShutdownLocations);
        }
        #endregion

        #region Load data to Combined towers combo
        private void LoadCombo()
        {
            ClosedStringList = new List<string>() { FIFPConstants.SHUTDOWN_CLOSEDSTRING_ALLSTRINGS, FIFPConstants.SHUTDOWN_CLOSEDSTRING_OILSTRINGS, FIFPConstants.SHUTDOWN_CLOSEDSTRING_WATERSTRINGS };
            SelectedClosedString = ClosedStringList[0];
        }
        #endregion

        #region Closed String combo filter
        private void ClosedStringFilter(ComboBox cmbFilter)
        {
            if (!string.IsNullOrEmpty(SelectedClosedString))
            {
                List<FIFPAppointment> selectedActivityLSD = SelectedActivity.LsdPlans;
                List<FIFPAppointment> listForScheduleView = new List<FIFPAppointment>();
                FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>();
                switch (SelectedClosedString)
                {
                    case FIFPConstants.SHUTDOWN_CLOSEDSTRING_ALLSTRINGS:
                        FilteredLinkedShutdownList.AddRange((from item in LinkedShutdownList
                                                             where (item.FluidType == FIFPConstants.FLUIDTYPE_WATER || item.FluidType == FIFPConstants.FLUIDTYPE_OIL || item.FluidType == FIFPConstants.FLUIDTYPE_COMBINED) && item.UnitType != FIFPConstants.UNITTYPE_STRING
                                                             select item).ToList<FIFPAppointment>());
                        
                        SelectedActivity.LsdPlans.ForEach(s => { s.IsLinkedShutdownPlan = true; });
                        break;
                    case FIFPConstants.SHUTDOWN_CLOSEDSTRING_OILSTRINGS:
                        FilteredLinkedShutdownList.AddRange((from item in LinkedShutdownList
                                                             where item.FluidType == FIFPConstants.FLUIDTYPE_OIL && item.UnitType != FIFPConstants.UNITTYPE_STRING
                                                             select item).ToList<FIFPAppointment>());
                        SelectedActivity.LsdPlans.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_WATER).ToList<FIFPAppointment>().ForEach(p => { p.IsLinkedShutdownPlan = false; });
                        break;
                    case FIFPConstants.SHUTDOWN_CLOSEDSTRING_WATERSTRINGS:
                        FilteredLinkedShutdownList.AddRange((from item in LinkedShutdownList
                                                             where item.FluidType == FIFPConstants.FLUIDTYPE_WATER && item.UnitType != FIFPConstants.UNITTYPE_STRING
                                                             select item).ToList<FIFPAppointment>());
                        SelectedActivity.LsdPlans.Where(s => s.FluidType == FIFPConstants.FLUIDTYPE_OIL).ToList<FIFPAppointment>().ForEach(p => { p.IsLinkedShutdownPlan = false; });
                        break;
                }



                if (FilteredLinkedShutdownList != null && filteredLinkedShutdownList.Count > 0 && SelectedActivity != null)
                    listForScheduleView.Add(SelectedActivity);
                listForScheduleView.AddRange(FilteredLinkedShutdownList);
                LoadTimelineView(listForScheduleView);
            }
        }
        #endregion

        #region Treeview selection changed event
        private void UnitTreeviewSelectionChanged(TreeView treeView)
        {
            IsApplyCrossLineEnabled = false;
            IsApplySIMOPSEnabled = false;
            IsCombinedTowerEnabled = false;
            FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>();
            Unit unit = treeView.SelectedItem as Unit;
            if (unit != null)
            {
                string selectedItem = Convert.ToString(unit.UnitName);
                if (!string.IsNullOrEmpty(selectedItem))
                {
                    ActivityListWithSelectedUnit = (from item in ActivityList
                                                    where item.UnitName == selectedItem
                                                    select item).ToList<FIFPAppointment>();
                }
            }
        }
        #endregion

        #region LoadTimelineView
        private void LoadTimelineView(List<FIFPAppointment> plans)
        {
            AppointmentGroup appointmentGroup = new AppointmentGroup();
            List<ResourceType> lstResources = new List<ResourceType>();
            List<Resource> unitList = new List<Resource>();
            ResourceType unitType = new ResourceType("Unit");
            unitType.DisplayName = "Unit";
            unitType.Name = "Unit";

            foreach (FIFPAppointment appointment in plans)
            {
                if (appointment != null)
                {
                    Resource resource = new Resource() { ResourceName = appointment.UnitName, DisplayName = appointment.UnitName, ResourceType = unitType.Name };
                    if (!unitList.Contains(resource))
                        unitList.Add(resource);
                    appointment.Resources.Add(resource);
                }
            }

            appointmentGroup.Appointments = new List<FIFPAppointment>(plans);
            unitType.Resources.AddRange(unitList);
            lstResources.Add(unitType);


            appointmentGroup.ResourceTypes = lstResources;
            appointmentGroup.UnitList = unitList;

            if (OnAppointmentDataCompleted != null)
                OnAppointmentDataCompleted(this, new CustomEventArgs<AppointmentGroup>(appointmentGroup));

        }
        #endregion

        #region ActivityDatagridSelectionChange
        private void ActivityDatagridSelectionChange(DataGrid activityGrid)
        {
            FIFPAppointment activity = (FIFPAppointment)activityGrid.SelectedItem;
            if (activity != null)
            {
                if (activity.FluidType == FIFPConstants.FLUIDTYPE_COMBINED)
                {
                    IsCombinedTowerEnabled = true;
                }
                else
                    IsCombinedTowerEnabled = false;

                //if ((activity.UnitType == FIFPConstants.UNITTYPE_WELL || activity.UnitType == FIFPConstants.UNITTYPE_STRING) && activity.ActivityType == FIFPConstants.ACTIVITY_TYPE_RIG)
                //    IsApplySIMOPSEnabled = true;
                //else
                //    IsApplySIMOPSEnabled = false;

                if ((activity.UnitType == FIFPConstants.UNITTYPE_TOWER && SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_TOWER) || (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL && activity.UnitType == FIFPConstants.UNITTYPE_WELL && activity.ActivityCode == FIFPConstants.ACTIVITY_TYPE_RIG))
                {
                    IsApplySIMOPSEnabled = true;
                    IsApplyCrossLineEnabled = true;
                }
                else
                {
                    IsApplySIMOPSEnabled = false;
                    IsApplyCrossLineEnabled = false;
                }


                if (activity.UnitType != FIFPConstants.UNITTYPE_TOWER)//For Tower activities we can apply SIMOPS and Crossing line. We can't enter reduced capcity for tower activities.
                    IsEnabledRaducedCapacity = true;
                else if (SelectedTreeViewUnit != null && (SelectedTreeViewUnit.UnitType != FIFPConstants.UNITTYPE_TOWER && SelectedTreeViewUnit.UnitType != FIFPConstants.UNITTYPE_WELL))
                    IsEnabledRaducedCapacity = true;
                else
                    IsEnabledRaducedCapacity = false;


                activity.Category = new Category("Oil", new SolidColorBrush(new Color() { R = 0x00, G = 0xFF, B = 0x00, A = 0xFF }));
                SelectedActivity = activity;
            }
        }
        #endregion

        #region Modified datagrid change
        private void ModifiedActivityDatagridSelectionChange(DataGrid activityGrid)
        {
            FIFPAppointment activity = (FIFPAppointment)activityGrid.SelectedItem;
            if (activity != null)
            {
                if (activity.ModificationReason == "SIMOPS applied")
                    IsCancelSIMOPSEnabled = true;
                else if (activity.ModificationReason == "Crossing line applied")
                    IsCancelCrossLineEnabled = true;

                ModifiedSelectedActivity = activity;
            }
        }

        #endregion

        #region Apply SIMOPS
        private void ReloadTimelineViewBySIMOPS(Button btnSIMOPS)
        {
            IsSIMOPS = true;
            if (SelectedActivity != null)
            {
                popup = new PercentagePopup();
                popup.Closed += new EventHandler(popup_Closed);
                popup.Show();
            }
            else
                MessageBox.Show("Please select Activity");
        }

        void popup_Closed(object sender, EventArgs e)
        {

        }
        #endregion

        #region Apply Crossing line
        private void ReloadTimelineViewByCrossingLine(Button btnSIMOPS)
        {
            IsSIMOPS = false;
            if (SelectedActivity != null)
            {
                if (SelectedActivity != null)
                {
                    popup = new PercentagePopup();
                    popup.Closed += new EventHandler(popup_Closed);
                    popup.Show();
                }
            }
            else
                MessageBox.Show("Please select Activity");
        }
        #endregion

        #region Location datagrid selection changed
        private void LSDLocationGridSelectionChange(DataGrid locationGrid)
        {
            ServiceLocator.Get<FilterVM>().SelectedDivision = ServiceLocator.Get<FilterVM>().DivisionList[0];
            if (locationGrid != null && locationGrid.SelectedItem != null)
            {
                TreeViewGrid.Children.Clear();
                IsEnabledRaducedCapacity = false;
                SelectedActivity = null;
                SelectedTreeViewUnit = null;
                SelectedLSDLocation = locationGrid.SelectedItem as Unit;
                if (SelectedLSDLocation != null)
                {
                    ServiceLocator.Get<FilterVM>().IsDivisionEnabled = true;
                    if (SelectedLSDLocation.UnitType != FIFPConstants.UNITTYPE_TOWER)
                    {
                        IsApplySIMOPSEnabled = false;
                        IsApplyCrossLineEnabled = false;
                    }
                    if (SelectedLSDLocation.FluidType == FIFPConstants.FLUIDTYPE_COMBINED)
                        ServiceLocator.Get<FilterVM>().IsCombinedTowerChecked = true;
                    else
                        ServiceLocator.Get<FilterVM>().IsCombinedTowerChecked = false;

                    //Comment out 27-01-2013
                    //if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_PIPELINE || (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL))
                    //    TreeViewUnitList = UnitList.Where(p => p.UnitID == SelectedLSDLocation.ParentUnitID).ToList<Unit>();
                    //else
                    //    TreeViewUnitList = new List<Unit>() { SelectedLSDLocation };

                    //if (SelectedLSDLocation.UnitType == FIFPConstants.UNITTYPE_WELL)
                    //    LoadTreeView(UnitList.Where(p => p.UnitID == SelectedLSDLocation.ParentUnitID).FirstOrDefault());
                    //else
                    LoadTreeView(SelectedLSDLocation);

                    ActivityListWithSelectedUnit = (from item in ActivityList
                                                    where item.UnitName == SelectedLSDLocation.UnitName
                                                    select item).ToList<FIFPAppointment>();


                    FilteredActivityListWithSelectedUnit = new ObservableCollection<FIFPAppointment>(ActivityListWithSelectedUnit);
                    List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();


                    foreach (FIFPAppointment appointment in ActivityListWithSelectedUnit)
                    {
                        lsdPlans.Add(appointment);
                        lsdPlans.AddRange(appointment.FilteredLsdPlans);
                    }
                    LinkedShutdownList = FilteredLinkedShutdownList = new ObservableCollection<FIFPAppointment>(lsdPlans);


                    LoadTimelineView(lsdPlans);
                }

            }
        }
        #endregion

        #region LoadTreeviewGrid
        private void LoadTreeviewGrid(Grid grdTreeView)
        {
            TreeViewGrid = grdTreeView;
        }
        #endregion

        #region LoadTreeView
        private void LoadTreeView(Unit selectedUnit)
        {
            if (selectedUnit != null)
            {
                TreeView treeView = new TreeView();
                treeView.Style = Application.Current.Resources["TreeViewStyleSMUR"] as Style;
                treeView.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(treeView_SelectedItemChanged);
                TreeViewItem rootItem = new TreeViewItem();

                rootItem.Header = selectedUnit.UnitName;
                rootItem.Tag = selectedUnit;
                rootItem.Foreground = selectedUnit.UnitNameTextColor;
                rootItem.IsExpanded = true;
                treeView.Items.Add(rootItem);
                TreeViewGrid.Children.Add(treeView);

                if (selectedUnit.UnitType == FIFPConstants.UNITTYPE_TOWER)
                    GeUnitNameList(new List<Unit>() { selectedUnit }, rootItem, true);
                else
                    GeUnitNameList(selectedUnit.ChildUnitList, rootItem, false);
            }
        }

        void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            TreeView treeView = sender as TreeView;
            if (treeView != null && treeView.SelectedItem != null)
            {
                TreeViewItem item = treeView.SelectedItem as TreeViewItem;
                if (item != null && item.Tag != null)
                {
                    Unit unit = item.Tag as Unit;
                    if (unit != null && (unit.UnitType != FIFPConstants.UNITTYPE_TOWER || unit.UnitType != FIFPConstants.UNITTYPE_WELL))
                        SelectedTreeViewUnit = unit;

                    if (SelectedActivity != null && (unit.UnitType != FIFPConstants.UNITTYPE_TOWER && unit.UnitType != FIFPConstants.UNITTYPE_WELL))
                        IsEnabledRaducedCapacity = true;
                    else
                        IsEnabledRaducedCapacity = false;
                }
            }

        }
        #endregion

        #region GetUnitNameListByTower
        private void GetUnitNameListByTower(List<Unit> lstUnits, Unit rootItem)
        {
            foreach (Unit unit in lstUnits)
            {
                if (unit.UnitType == FIFPConstants.UNITTYPE_TOWER)
                {
                    rootItem.TowerUnitList = UnitList.Where(p => p.ParentUnitID == unit.UnitID).ToList();
                }
                GetUnitNameListByTower(unit.ChildUnitList, rootItem);
            }
        }
        #endregion

        #region Get Treeview UnitList
        private void GeUnitNameList(List<Unit> lstUnits, TreeViewItem rootItem, bool bInitial)
        {
            foreach (Unit unit in lstUnits)
            {
                if (unit.UnitType == FIFPConstants.UNITTYPE_TOWER)
                {
                    TreeViewItem towerNode = new TreeViewItem();
                    if (bInitial)
                    {
                        if (lstUnits != null && lstUnits[0] != null && lstUnits[0].ChildUnitList != null && lstUnits[0].ChildUnitList.Count > 0)
                        {
                            foreach (Unit childUnit in lstUnits[0].ChildUnitList)
                            {
                                if (childUnit.UnitType != FIFPConstants.UNITTYPE_TOWER)
                                {
                                    TreeViewItem node = new TreeViewItem();
                                    node.Header = childUnit.UnitName;
                                    node.Tag = childUnit;
                                    node.Foreground = childUnit.UnitNameTextColor;
                                    node.IsExpanded = false;
                                    rootItem.Items.Add(node);
                                    if (childUnit.UnitType == FIFPConstants.UNITTYPE_WELL)
                                    {
                                        foreach (Unit stringUnit in childUnit.ChildUnitList)
                                        {
                                            TreeViewItem childNode = new TreeViewItem();
                                            childNode.Header = stringUnit.UnitName;
                                            childNode.Tag = stringUnit;
                                            childNode.Foreground = stringUnit.UnitNameTextColor;
                                            childNode.IsExpanded = false;
                                            node.Items.Add(childNode);
                                        }
                                    }
                                }
                            }
                        }
                        bInitial = false;
                    }
                    else
                    {
                        towerNode.Header = unit.UnitName;
                        towerNode.Tag = unit;
                        towerNode.Foreground = unit.UnitNameTextColor;
                        towerNode.IsExpanded = false;
                        rootItem.Items.Add(towerNode);
                    }
                    foreach (Unit childUnit in unit.ChildUnitList)
                    {
                        TreeViewItem node = new TreeViewItem();
                        node.Header = childUnit.UnitName;
                        node.Tag = childUnit;
                        node.Foreground = childUnit.UnitNameTextColor;
                        node.IsExpanded = false;
                        if (childUnit.UnitType == FIFPConstants.UNITTYPE_WELL)
                        {
                            foreach (Unit stringUnit in childUnit.ChildUnitList)
                            {
                                TreeViewItem childNode = new TreeViewItem();
                                childNode.Header = stringUnit.UnitName;
                                childNode.Tag = stringUnit;
                                childNode.Foreground = stringUnit.UnitNameTextColor;
                                childNode.IsExpanded = false;
                                node.Items.Add(childNode);
                            }
                        }
                        towerNode.Items.Add(node);
                    }
                }
                GeUnitNameList(unit.ChildUnitList, rootItem, bInitial);
            }
        }
        #endregion

        #region HidePopup
        private void HidePopup(Button btnCancel)
        {
            CapacityPercentage = 0;
            if (popup != null)
                popup.Close();
        }
        #endregion

        #region ShowPopup
        private void ShowPopup(Button btnShow)
        {
            if (CheckPercentageValidation())
            {
                if (SelectedActivity != null)
                {
                    if (IsSIMOPS)
                    {
                        List<int> wellUnitIds = SelectedActivity.LsdPlans.Where(s => s.UnitType == FIFPConstants.UNITTYPE_WELL && s.ActivityCode != FIFPConstants.ACTIVITY_TYPE_RIG).Select(s => s.UnitID).Distinct().ToList<int>();
                        List<int> stringUnitIds = UnitList.Where(u => wellUnitIds.Any(s => s.Equals(u.ParentUnitID))).Select(p => p.UnitID).ToList<int>();
                        SelectedActivity.ModificationReason = "SIMOPS applied";
                        foreach (FIFPAppointment appointment in SelectedActivity.LsdPlans.Where(w => stringUnitIds.Any(s => s.Equals(w.UnitID))))
                        {
                            appointment.ModificationReason = "SIMOPS applied";
                            appointment.CapacityPercentage = Math.Round(Convert.ToDouble((CapacityPercentage / 100)), 2);
                        }
                    }
                    else
                    {
                        List<int> wellUnitIds = SelectedActivity.LsdPlans.Where(s => s.UnitType == FIFPConstants.UNITTYPE_WELL && s.ActivityCode != FIFPConstants.ACTIVITY_TYPE_RIG).Select(s => s.UnitID).Distinct().ToList<int>();
                        List<int> parentUnitWellIds = UnitList.Where(u => u.ParentUnitID == SelectedActivity.UnitID && u.UnitType == FIFPConstants.UNITTYPE_WELL).Select(p => p.UnitID).ToList<int>();
                        wellUnitIds = new List<int>(wellUnitIds.Except(parentUnitWellIds));
                        List<int> stringUnitIds = UnitList.Where(u => wellUnitIds.Any(s => s.Equals(u.ParentUnitID))).Select(p => p.UnitID).ToList<int>();
                        SelectedActivity.ModificationReason = "Crossing line applied";
                        foreach (FIFPAppointment appointment in SelectedActivity.LsdPlans.Where(w => stringUnitIds.Any(s => s.Equals(w.UnitID))))
                        {
                            appointment.ModificationReason = "Crossing line";
                            appointment.CapacityPercentage = Math.Round(Convert.ToDouble((CapacityPercentage / 100)), 2);
                        }
                    }
                }

                ModifiedLinkedShutdownList.Add(SelectedActivity);
                FilteredActivityListWithSelectedUnit = new ObservableCollection<FIFPAppointment>(FilteredActivityListWithSelectedUnit.Where(f => f.PlanID != SelectedActivity.PlanID));

                //Load Timeline View
                List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
                foreach (FIFPAppointment appointment in FilteredActivityListWithSelectedUnit)
                {
                    lsdPlans.Add(appointment);
                    lsdPlans.AddRange(appointment.FilteredLsdPlans);// Need to check IsLinkedShutDown = true
                }
                LoadTimelineView(lsdPlans);

                //Reset properties
                IsApplySIMOPSEnabled = false;
                IsApplyCrossLineEnabled = false;
                _validationResults.Clear();
                CapacityPercentage = 100;
                popup.Close();
            }
        }
        #endregion

        #region CancelSIMOPS
        private void CancelSIMOPS(Button btnCancel)
        {
            if (ModifiedSelectedActivity != null)
            {
                List<int> wellUnitIds = ModifiedSelectedActivity.LsdPlans.Where(s => s.UnitType == FIFPConstants.UNITTYPE_WELL && s.ActivityCode != FIFPConstants.ACTIVITY_TYPE_RIG).Select(s => s.UnitID).Distinct().ToList<int>();
                List<int> stringUnitIds = unitList.Where(u => wellUnitIds.Any(s => s.Equals(u.ParentUnitID))).Select(p => p.UnitID).ToList<int>();

                foreach (FIFPAppointment appointment in ModifiedSelectedActivity.LsdPlans.Where(w => stringUnitIds.Any(s => s.Equals(w.UnitID))))
                {
                    appointment.ModificationReason = string.Empty;
                    appointment.CapacityPercentage = appointment.End.Subtract(appointment.Start).TotalDays * 100;
                }
            }
            ModifiedSelectedActivity.ModificationReason = string.Empty;

            FilteredActivityListWithSelectedUnit.AddRange(ModifiedLinkedShutdownList.Where(f => f.PlanID == ModifiedSelectedActivity.PlanID));
            ModifiedLinkedShutdownList = new ObservableCollection<FIFPAppointment>(ModifiedLinkedShutdownList.Where(f => f.PlanID != ModifiedSelectedActivity.PlanID));
            //Load Timeline View
            List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
            foreach (FIFPAppointment appointment in FilteredActivityListWithSelectedUnit)
            {
                lsdPlans.Add(appointment);
                lsdPlans.AddRange(appointment.FilteredLsdPlans);// Need to check IsLinkedShutDown = true
            }
            if (ModifiedLinkedShutdownList != null && ModifiedLinkedShutdownList.Count == 0)
                IsCancelSIMOPSEnabled = IsCancelCrossLineEnabled = false;
            LoadTimelineView(lsdPlans);
        }
        #endregion

        #region CancelCrossingLine
        private void CancelCrossingLine(Button btnCancel)
        {
            //TODO Make this as Generic function
            if (ModifiedSelectedActivity != null)
            {
                List<int> wellUnitIds = ModifiedSelectedActivity.LsdPlans.Where(s => s.UnitType == FIFPConstants.UNITTYPE_WELL && s.ActivityCode != FIFPConstants.ACTIVITY_TYPE_RIG).Select(s => s.UnitID).Distinct().ToList<int>();
                List<int> parentUnitWellIds = UnitList.Where(u => u.ParentUnitID == SelectedActivity.UnitID && u.UnitType == FIFPConstants.UNITTYPE_WELL).Select(p => p.UnitID).ToList<int>();
                wellUnitIds = new List<int>(wellUnitIds.Except(parentUnitWellIds));
                List<int> stringUnitIds = UnitList.Where(u => wellUnitIds.Any(s => s.Equals(u.ParentUnitID))).Select(p => p.UnitID).ToList<int>();
                SelectedActivity.ModificationReason = string.Empty;
                foreach (FIFPAppointment appointment in ModifiedSelectedActivity.LsdPlans.Where(w => stringUnitIds.Any(s => s.Equals(w.UnitID))))
                {
                    appointment.ModificationReason = string.Empty;
                    appointment.CapacityPercentage = appointment.End.Subtract(appointment.Start).TotalDays * 100;
                }
            }
            ModifiedSelectedActivity.ModificationReason = string.Empty;

            FilteredActivityListWithSelectedUnit.AddRange(ModifiedLinkedShutdownList.Where(f => f.PlanID == ModifiedSelectedActivity.PlanID));
            ModifiedLinkedShutdownList = new ObservableCollection<FIFPAppointment>(ModifiedLinkedShutdownList.Where(f => f.PlanID != ModifiedSelectedActivity.PlanID));
            //Load Timeline View
            List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
            foreach (FIFPAppointment appointment in FilteredActivityListWithSelectedUnit)
            {
                lsdPlans.Add(appointment);
                lsdPlans.AddRange(appointment.FilteredLsdPlans);
            }
            LoadTimelineView(lsdPlans);
        }
        #endregion

        #region SearchByUnitName
        private void SearchByUnitName(object e)
        {
            var binding = txtSearch.GetBindingExpression(TextBox.TextProperty);
            binding.UpdateSource();
            KeyEventArgs args = e as KeyEventArgs;
            if (args != null && args.Key == Key.Enter)
            {
                if (CheckUnitNameValidation())
                {
                    TreeViewUnitList = UnitList.Where(p => p.UnitName == UnitName).ToList<Unit>();
                }
            }
        }
        #endregion

        #region Load Textbox
        TextBox txtSearch = null;
        private void LoadTextBox(TextBox txtBox)
        {
            txtSearch = txtBox;
        }
        #endregion

        #region CheckUnitNameValidation
        private bool CheckPercentageValidation()
        {
            bool bRet = true;

            if (string.IsNullOrEmpty(Convert.ToString(CapacityPercentage)))
            {
                bRet = false;
                NotifyPropertyChanged(() => CapacityPercentage);
            }
            else if (!string.IsNullOrEmpty(Convert.ToString(CapacityPercentage)) && CapacityPercentage < 0 && CapacityPercentage > 100)
            {
                bRet = false;
                NotifyPropertyChanged(() => CapacityPercentage);
            }
            else
            {
                bRet = true;
                NotifyPropertyChanged(() => CapacityPercentage);
            }
            return bRet;
        }
        #endregion

        #region CheckUnitNameValidation
        private bool CheckUnitNameValidation()
        {
            bool bRet = true;

            if (string.IsNullOrEmpty(UnitName))
            {
                bRet = false;
                IsUnitNameExist = false;
                NotifyPropertyChanged(() => UnitName);
            }
            else if (!string.IsNullOrEmpty(UnitName) && UnitList.Where(s => s.UnitName == UnitName).FirstOrDefault() == null)
            {
                bRet = false;
                IsUnitNameExist = true;
                NotifyPropertyChanged(() => UnitName);
            }
            else
            {
                bRet = true;
                IsUnitNameExist = false;
                NotifyPropertyChanged(() => UnitName);
            }
            return bRet;
        }

        #region CalculateReducedCapacity
        private void CalculateReducedCapacity(object e)
        {
            var binding = txtRC.GetBindingExpression(TextBox.TextProperty);
            binding.UpdateSource();
            KeyEventArgs args = e as KeyEventArgs;
            if (args != null && args.Key == Key.Enter)
            {
                List<int> wellUnitIds = SelectedActivity.LsdPlans.Where(s => s.UnitType == FIFPConstants.UNITTYPE_WELL && s.ActivityCode != FIFPConstants.ACTIVITY_TYPE_RIG).Select(s => s.UnitID).Distinct().ToList<int>();
                List<int> stringUnitIds = UnitList.Where(u => wellUnitIds.Any(s => s.Equals(u.ParentUnitID))).Select(p => p.UnitID).ToList<int>();
                foreach (FIFPAppointment appointment in SelectedActivity.LsdPlans.Where(w => stringUnitIds.Any(s => s.Equals(w.UnitID))))
                {
                    appointment.ReducedCapacity = ReducedCapacity;
                }

            }
        }
        #endregion

        #region Load Reduced Capcity Textbox
        TextBox txtRC = null;
        private void LoadRCTextBox(TextBox txtBox)
        {
            txtRC = txtBox;
        }
        #endregion
        #endregion

        #region Validation
        protected void NotifyPropertyChanged(Expression<Func<object>> propertyExpression)
        {
            if (propertyExpression == null)
                throw new ArgumentNullException(FIFPConstants.propertyExpression);

            var propertyName = GetPropertyName(propertyExpression);
            OnPropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            Validate(propertyName);
            OnNotifyPropertyChanged();
        }

        protected virtual void OnNotifyPropertyChanged() { }

        private string GetPropertyName(Expression<Func<object>> propertyExpression)
        {
            var unaryExpression = propertyExpression.Body as UnaryExpression;
            var memberExpression = unaryExpression == null ? (MemberExpression)propertyExpression.Body : (MemberExpression)unaryExpression.Operand;

            var propertyName = memberExpression.Member.Name;

            return propertyName;
        }


        private void NotifyErrorsChanged(string propertyName)
        {
            ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
        }

        protected void Validate(string propertyName)
        {
            var value = GetPropertyValue(propertyName);
            RemoveErrorsForProperty(propertyName);
            Validator.TryValidateProperty(value, new ValidationContext(this, null, null) { MemberName = propertyName }, _validationResults);
            NotifyErrorsChanged(propertyName);
        }

        protected void Validate()
        {
            _validationResults.Clear();
            Validator.TryValidateObject(this, new ValidationContext(this, null, null), _validationResults, true);

            foreach (var result in _validationResults)
                NotifyErrorsChanged(result.MemberNames.First());

        }

        private object GetPropertyValue(string propertyName)
        {
            var type = this.GetType();

            var propertyInfo = type.GetProperty(propertyName);

            if (propertyInfo == null)
            {
                throw new ArgumentException(string.Format(FIFPConstants.Couldntfindanyproperty, propertyName, type));
            }

            return propertyInfo.GetValue(this, null);
        }

        private void RemoveErrorsForProperty(string propertyName)
        {
            var validationResults = _validationResults.Where(result => result.MemberNames.Contains(propertyName)).ToList();

            foreach (var result in validationResults)
                _validationResults.Remove(result);
        }

        public IEnumerable GetErrors(string propertyName)
        {
            return _validationResults.Where(result => result.MemberNames.Contains(propertyName));
        }

        public bool HasErrors
        {
            get { return _validationResults.Any(); }
        }

        public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
        //public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
}
